package com.sdy.dataexchange.meta.job;

import com.sdy.common.utils.DateUtil;
import com.sdy.dataexchange.biz.model.ExDbDict;
import com.sdy.dataexchange.biz.service.ExDbDictService;
import com.sdy.dataexchange.meta.model.MetadataClassdbMapping;
import com.sdy.dataexchange.meta.model.MetadataColumn;
import com.sdy.dataexchange.meta.model.MetadataErrorRecord;
import com.sdy.dataexchange.meta.model.MetadataModel;
import com.sdy.dataexchange.meta.service.*;
import com.sdy.dataexchange.meta.util.ColumnUtil;
import com.sdy.dataexchange.meta.util.JdbcUtil;
import com.sdy.dataexchange.meta.util.TableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: 王越洋
 * @version: v1.0
 * @description: com.sdy.dataexchange.task
 * @date:2019/11/7
 */
@Slf4j
@Component
public class MetadataTask {
    @Autowired
    private MetadataClassdbMappingService metadataClassdbMappingService;
    @Autowired
    private JdbcUtil jdbcUtil;
    @Autowired
    private MetadataColumnService metadataColumnService;
    @Autowired
    private MetadataModelService metadataModelService;
    @Autowired
    private TableUtil tableUtil;
    @Autowired
    private MetadataErrorRecordService metadataErrorRecordService;
    @Autowired
    private ExDbDictService exDbDictService;
    @Autowired
    private ColumnUtil columnUtil;
    @Autowired
    private MetadataModelLogService metadataModelLogService;
    @Autowired
    private MetadataColumnLogService metadataColumnLogService;

    /**
     * 全部 库表 更新  适用于 大更新
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public void allTabErrorDispose() throws InstantiationException, IllegalAccessException {
        List<MetadataClassdbMapping> metadataClassdbMappings = metadataClassdbMappingService.queryAll();
        for (MetadataClassdbMapping mcm:metadataClassdbMappings) {
            tabComparison(mcm.getDbId());
            List<MetadataModel> models = metadataModelService.queryDbTabMod(mcm.getDbId());
            for (MetadataModel mm:models) {
                cloumnComparison(mm);
            }
        }
    }

    /**
     * 单个 库 更新 适用于 新添加的库更新
     * @param dbId
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public void oneTabErrorDispose(Integer dbId) throws InstantiationException, IllegalAccessException {
        List<MetadataErrorRecord>  metadataErrorRecordList = tabComparison(dbId);
        List<MetadataModel> models = metadataModelService.queryDbTabMod(dbId);
        for (MetadataModel mm:models) {
            cloumnComparison(mm);
        }
    }
    
    
    

    /**
     * 单个库 所有表
     * @param dbId
     * @return List<MetadataErrorRecord>
     */
    private  List<MetadataErrorRecord> tabComparison(Integer dbId){
        //从数据源获取新表模型
        List<MetadataModel> newModels = metadataModelService.queryAllTabMod(metadataClassdbMappingService.queryGetById(dbId).get(0));
        //把新纪录添加到表中
        metadataModelLogService.addAllModLog(newModels);
        //查询历史表模型
        List<MetadataModel> formerModels = metadataModelService.queryDbTabMod(dbId);
        if (!newModels.isEmpty()){
            //对比
            List<MetadataErrorRecord> comResulMap = tableUtil.getComResulMap(formerModels, newModels);
            if (!comResulMap.isEmpty()){
                //处理表结构
                Integer integer = tabErrorDispose(comResulMap, dbId);
                return comResulMap;
            }else {
             log.info("当前库 元数据 一切正常");
             return null;
            }
        }else {
            log.info("当前库已经不存在 请重新检查!");
            return null;
        }
    }

    /**
     * 单个库 表错误 处理
     * @param comResulMap
     * @param dbId
     * @return
     */
    private Integer tabErrorDispose(List<MetadataErrorRecord> comResulMap ,Integer dbId){
        for (MetadataErrorRecord mer : comResulMap) {
            //给入当前Dbid
            mer.setDbId(dbId);
            // 清除错误数据
            switch (mer.getErrorType()) {
                //删除表字段 以及表
                case 1:
                    metadataColumnService.delAllTabColums(mer.getModId());
                    metadataModelService.delByIdTabMod(mer.getModId(), mer.getTableName());
                    break;
                case 2:
                    //添加表字段以及表
                    ExDbDict dbInfo = exDbDictService.getById(mer.getDbId());
                    MetadataModel metadataModel = new MetadataModel();
                    metadataModel.setDbId(mer.getDbId());
                    metadataModel.setModelType(1);
                    metadataModel.setModelName(mer.getTableName());
                    metadataModel.setModelIdentifying(dbInfo.getDbIp() + "/" + dbInfo.getDbName() + "/" + dbInfo.getDbUser());
                    metadataModel.setModelCoding(dbInfo.getDbType());
                    Integer integer = metadataModelService.addByTabMod(metadataModel);
                    mer.setModId(metadataModel.getId());
                    break;
                default:
            }
        }
        Integer integer = metadataErrorRecordService.addTabError(comResulMap);
        if (integer>0){
            return 1;
        }else {
            return 0;
        }
    }


    /**
     * 全部表 表字段更新
     */
    public void allColumnErrorDispose() throws InstantiationException, IllegalAccessException {
        List<MetadataModel> models = metadataModelService.queryAllTabMod();
        for (MetadataModel m : models) {
            cloumnComparison(m);
        }
    }


    /**
     * 处理单个表 表字段更新
     * @param m
     * @return
     */
    public  Integer cloumnComparison(MetadataModel m) {
        ExDbDict dbInfo = exDbDictService.getById(m.getDbId());
        List<MetadataColumn> tabColumns = new ArrayList<>();
        if (dbInfo.getDbType().equals("ORACLE")){
            try {
                tabColumns = metadataColumnService.queryOracleTabColumns(dbInfo, 1, m.getModelName());
            } catch (Exception e) {
                log.error("ORACLE 出错 ",e);
            }
        }else if (dbInfo.getDbType().equals("MYSQL")){
            try {
                tabColumns = metadataColumnService.queryMysqlTabColumns(dbInfo,m.getModelName());
            } catch (Exception e) {
                log.error("MYSQL 出错",e);
            }
        }
        for (MetadataColumn mdc:tabColumns) {
            mdc.setTableId(m.getId());
        }
        //计入log中
        metadataColumnLogService.addAllColumnLog(tabColumns);
        List<MetadataColumn> metadataColumns = metadataColumnService.queryByModId(m.getId());
        if (!tabColumns.isEmpty()) {
            List<MetadataErrorRecord> comResulMap = columnUtil.getComResulMap(metadataColumns, tabColumns);
            if (!comResulMap.isEmpty()){
                Integer integer = columnErrorDispose(comResulMap, m);
                return integer;
            }else {
                log.info("此表模型未改变!");
                return null;
            }
        }else {
            log.info(" {} 此表已经不存在!",m.getModelName());
            return null;
        }
    }

    /**
     * 表错误处理
     * @param comResulMap
     * @param m
     * @return
     */
    private Integer columnErrorDispose(List<MetadataErrorRecord> comResulMap, MetadataModel m){
            for (MetadataErrorRecord mer : comResulMap) {
                mer.setDbId(m.getDbId());
                switch (mer.getErrorType()) {
                    case 11:
                        //把记录表里字段删除
                        Integer integer = metadataColumnService.delByColIdColumn(mer.getColId());
                        break;
                    case 12:
                        //记录表字段添加
                        MetadataColumn metadataColumn = mer.getMetadataColumn();
                        metadataColumn.setTableId(m.getId());
                        metadataColumn.setOperationTime(new Date());
                        boolean save = metadataColumnService.save(metadataColumn);
                        mer.setColId(metadataColumn.getId());
                        break;
                    case 13:
                        //表字段类型修改
                        metadataColumnService.updByIdTabColumns(mer.getColId(), mer.getErrorType(), mer.getMetadataColumn());
                        break;
                    case 14:
                        //字段长度改变
                        metadataColumnService.updByIdTabColumns(mer.getColId(), mer.getErrorType(), mer.getMetadataColumn());
                        break;
                    case 15:
                        //字段是否为空改变
                        metadataColumnService.updByIdTabColumns(mer.getColId(), mer.getErrorType(), mer.getMetadataColumn());
                        break;
                    case 16:
                        //字段是否主键改变
                        metadataColumnService.updByIdTabColumns(mer.getColId(), mer.getErrorType(), mer.getMetadataColumn());
                        break;
                    default:
                }
            }
        Integer integer = metadataErrorRecordService.addTabError(comResulMap);
        return integer;
    }
}
